package de.tabiteuea.gui.handlers;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;

import de.tabiteuea.gui.Messages;
import de.tabiteuea.gui.models.InputModel;
import de.tabiteuea.gui.models.ModelProvider;
import de.tabiteuea.gui.utils.ITabiXMLConstants;

/**
 * Handler persists the model in a XML file at a user defined location
 * 
 * @author Sebastian Lippert
 * 
 */

public class SaveAsProjectHandler extends AbstractHandler {

	/**
	 * Enables the save button in the gui depending on the existence of a
	 * saveable model
	 * 
	 */

	@Override
	public boolean isEnabled() {

		ModelProvider provider = ModelProvider.getInstance();
		return provider.isSaveAllowed();

	}

	/**
	 * Execute handler
	 */

	@Override
	public Object execute(ExecutionEvent event) throws ExecutionException {

		// get the actual model form the Provider
		ModelProvider provider = ModelProvider.getInstance();
		InputModel model = provider.getInputModel();

		// call dialog to define the location
		IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench()
				.getActiveWorkbenchWindow();
		FileDialog fileDialog = new FileDialog(
				activeWorkbenchWindow.getShell(), SWT.SAVE);
		fileDialog.setText(Messages.ResultView_save);
		fileDialog.setFilterExtensions(new String[] { "*.tabi" });

		// set new path at the model
		String savePath = fileDialog.open();
		if (savePath == null || savePath.isEmpty())
			return null;

		model.setSavePath(savePath);

		try {

			// create XML writer to save project
			XMLOutputFactory factory = XMLOutputFactory.newInstance();
			XMLStreamWriter writer;

			// write all attributes from the model to the file
			writer = factory.createXMLStreamWriter(new FileOutputStream(model
					.getSavePath()));
			writer.writeStartDocument();
			writer.writeCharacters("\n");

			writer.writeStartElement(ITabiXMLConstants.PROJECT_TAG);
			writer.writeAttribute(ITabiXMLConstants.PROJECT_NAME_ATTR,
					model.getProjectName());
			writer.writeAttribute(ITabiXMLConstants.FILE_PATH_ATTR,
					model.getFilePath());
			writer.writeAttribute(ITabiXMLConstants.FILE_NAME_ATTR,
					model.getFileName());
			writer.writeAttribute(ITabiXMLConstants.TEXT_LANGUAGE_ATTR, model
					.getTextLanguage().toString());
			writer.writeAttribute(ITabiXMLConstants.BASEFORM_ATTR,
					((Boolean) model.isUseBaseform()).toString());
			writer.writeAttribute(ITabiXMLConstants.WORD_DELIMIT_ATTR,
					model.getWordDelimiter());
			writer.writeAttribute(
					ITabiXMLConstants.WORD_DELIMITER_IS_REGEX_ATTR,
					((Boolean) model.isWordDelIsRegExp()).toString());
			writer.writeAttribute(ITabiXMLConstants.SENTENCE_DELIMIT_ATTR,
					model.getSentenceDelimiter());
			writer.writeAttribute(
					ITabiXMLConstants.SENTENCE_DELIMITER_IS_REGEX_ATTR,
					((Boolean) model.isSenDelIsRegExp()).toString());

			// wordList
			for (String s : model.getWordList()) {
				writer.writeCharacters("\n\t");
				writer.writeStartElement(ITabiXMLConstants.WORD_COVERAGE_ATTR);
				writer.writeCharacters(s);
				writer.writeEndElement();
			}

			writer.writeCharacters("\n");
			writer.writeEndElement();

			writer.writeCharacters("\n");
			writer.writeEndDocument();
			writer.close();

		}
		
		// exception handling will catch errors an recall this handler to
		// open the file dialog again
		catch (FileNotFoundException e) {
			MessageDialog.openError(
					PlatformUI.getWorkbench().getActiveWorkbenchWindow()
							.getShell(),
					Messages.ResultView_export_error,
					Messages.ResultView_export_error_desc + " "
							+ e.getLocalizedMessage());
			//recall handler
			execute(event);
		} catch (XMLStreamException e) {
			MessageDialog.openError(
					PlatformUI.getWorkbench().getActiveWorkbenchWindow()
							.getShell(),
					Messages.ResultView_export_error,
					Messages.ResultView_export_error_desc + " "
							+ e.getLocalizedMessage());
			//recall handler
			execute(event);
		}

		return null;
	}

}
